home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / mush5.7 / part08 < prev    next >
Encoding:
Internet Message Format  |  1987-09-19  |  48.3 KB

  1. Subject:  v11i058:  Mail user's shell, Part08/12
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: island!argv@Sun.COM (Dan Heller)
  7. Posting-number: Volume 11, Issue 58
  8. Archive-name: mush5.7/Part08
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 8 (of 12)."
  17. # Contents:  hdrs.c tool_help
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'hdrs.c' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'hdrs.c'\"
  21. else
  22. echo shar: Extracting \"'hdrs.c'\" \(23014 characters\)
  23. sed "s/^X//" >'hdrs.c' <<'END_OF_FILE'
  24. X/* hdr_procs.c     (c) copyright 1986 (Dan Heller) */
  25. X
  26. X/* hdrs.h -- routines that look at message headers */
  27. X#include "mush.h"
  28. X
  29. X/*
  30. X * get which message via the offset and search for the headers which
  31. X * match the string "str". there may be more than one of a field (like Cc:)
  32. X * so get them all and "cat" them together into the static buffer
  33. X * "buf" and return its address.
  34. X */
  35. Xchar *
  36. Xheader_field(n, str)
  37. Xchar *str;
  38. X{
  39. X    static char    buf[BUFSIZ];
  40. X    char        tmp[BUFSIZ];
  41. X    register char  *p, *p2, *b = buf;
  42. X    int contd_hdr;  /* true if next line is a continuation of the hdr we want */
  43. X
  44. X    if (fseek(tmpf, msg[n].m_offset, L_SET) != 0) {
  45. X    error("fseek in %s (msg %d, folder=%s)", tempfile, n+1, mailfile);
  46. X    turnon(glob_flags, READ_ONLY);
  47. X    return NULL;
  48. X    }
  49. X    *b = 0;
  50. X    while((p = fgets(tmp, BUFSIZ, tmpf)) && *p != '\n') {
  51. X    if (*p != ' ' && *p != '\t') {
  52. X        contd_hdr = 0;
  53. X        /* strcmp ignoring case */
  54. X        for(p2 = str; *p && *p2 && *p2 == lower(*p); ++p, ++p2);
  55. X        /* MATCH is true if p2 is at the end of str and *p is ':' */
  56. X        if (*p2 || *p++ != ':')
  57. X        continue;
  58. X        else
  59. X        contd_hdr = 1;
  60. X    } else if (!contd_hdr)
  61. X        continue;
  62. X    skipspaces(0);
  63. X    p2 = no_newln(p);
  64. X    *++p2 = ' ', *++p2 = 0;
  65. X    b += Strcpy(b, p);
  66. X    }
  67. X    if (b > buf) /* now get rid of the trailing blank */
  68. X    *--b = 0;
  69. X    return (*buf)? buf: NULL;
  70. X}
  71. X
  72. Xdo_hdrs(argc, argv, list)
  73. Xregister char **argv, list[];
  74. X{
  75. X    register int   pageful = 0, fnd;
  76. X    int        (*oldint)(), (*oldquit)(), show_deleted;
  77. X    static int     cnt;
  78. X    register char  *p;
  79. X    char        first_char = (argc) ? **argv: 'h';
  80. X
  81. X    if (!msg_cnt) {
  82. X    if (isoff(glob_flags, DO_PIPE))
  83. X        return;
  84. X#ifdef CURSES
  85. X    if (iscurses)
  86. X        clear();
  87. X#endif CURSES
  88. X#ifdef SUNTOOL
  89. X    if (istool)
  90. X        mail_status(0);
  91. X#endif SUNTOOL
  92. X    return 0;
  93. X    }
  94. X    if (first_char == ':' || (argc > 1 && argv[1][0] == ':')) {
  95. X    if (first_char != ':')
  96. X        argv++;
  97. X    return specl_hdrs(argv, list);
  98. X    }
  99. X
  100. X    if (argc > 1 && !strcmp(argv[1], "-?"))
  101. X    return help(0, "headers", cmd_help);
  102. X
  103. X    on_intr();
  104. X
  105. X    if (argc && (argv[0][1] == '+' || argc > 1 && !strcmp(argv[1], "+")) ||
  106. X        first_char == 'z' && !argv[1])
  107. X    if (msg_cnt > screen)
  108. X        cnt = min(msg_cnt - screen, n_array[0] + screen);
  109. X    else
  110. X        cnt = 0;
  111. X    else if (argc && (argv[0][1] == '-' || argc > 1 && !strcmp(argv[1], "-")))
  112. X    cnt = max((cnt - 2*screen), 0);
  113. X    else if (argc && *++argv &&
  114. X    (isdigit(**argv) || **argv == '^' || **argv == '$')
  115. X     || ison(glob_flags, IS_PIPE)) {
  116. X    /* if we're coming from a pipe, start display at the first msg bit
  117. X     * set in the msg_list
  118. X     */
  119. X    if (ison(glob_flags, IS_PIPE)) {
  120. X        if (isoff(glob_flags, DO_PIPE))
  121. X        for (fnd = 0; fnd < msg_cnt; fnd++)
  122. X            if (msg_bit(list, fnd))
  123. X            wprint("%s\n", compose_hdr(fnd));
  124. X        off_intr();
  125. X        return 0;
  126. X    }
  127. X    /* if a number was given, use it */
  128. X    if (!(fnd = chk_msg(*argv))) {
  129. X        off_intr();
  130. X        return -1;
  131. X    }
  132. X    for (cnt = fnd - 1; cnt > 0 && cnt + screen > msg_cnt; cnt--);
  133. X    } else if (current_msg < n_array[0] || current_msg > n_array[screen-1])
  134. X    cnt = current_msg; /* adjust if user reads passed screen bounds */
  135. X    else if (cnt >= msg_cnt || !argc || !*argv)
  136. X    cnt = max((cnt - screen), 0); /* adjust window to maintian position */
  137. X
  138. X    show_deleted = !!do_set(set_options, "show_deleted");
  139. X
  140. X    for (;pageful<screen && cnt<msg_cnt && isoff(glob_flags, WAS_INTR); cnt++) {
  141. X    if (!iscurses && !show_deleted && first_char == 'h'
  142. X        && ison(msg[cnt].m_flags, DELETE))
  143. X        continue;
  144. X    n_array[pageful++] = cnt;
  145. X    /* this message was displayed -- set the bit */
  146. X    if (list)
  147. X        set_msg_bit(list, cnt);
  148. X    /* if do_pipe, don't output anything */
  149. X    if (ison(glob_flags, DO_PIPE))
  150. X        continue;
  151. X    p = compose_hdr(cnt);
  152. X    if (!istool && (!iscurses || ison(glob_flags, IS_GETTING)))
  153. X        puts(p);
  154. X#ifdef SUNTOOL
  155. X    else if (istool) {
  156. X        if (cnt == current_msg) /* embolden or reverse_video */
  157. X        highlight(hdr_win, 0,pageful*l_height(DEFAULT), DEFAULT,p);
  158. X        else
  159. X        pw_text(hdr_win, 0, pageful * l_height(DEFAULT), PIX_SRC,
  160. X                            fonts[DEFAULT], p);
  161. X        Clrtoeol(hdr_win, strlen(p)*l_width(DEFAULT),
  162. X             pageful*l_height(DEFAULT), DEFAULT);
  163. X    }
  164. X#endif SUNTOOL
  165. X#ifdef CURSES
  166. X        else if (iscurses)
  167. X        mvprintw(pageful, 0, "%-*s", COLS-2, p);
  168. X#endif CURSES
  169. X    }
  170. X    /* just in case a signal stopped us */
  171. X    off_intr();
  172. X    pageful++;
  173. X#ifdef CURSES
  174. X    if (iscurses && pageful < screen)
  175. X    move(pageful, 0), clrtobot();
  176. X#endif CURSES
  177. X    if (cnt == msg_cnt) {
  178. X    while (pageful <= screen) {
  179. X        n_array[pageful-1] = msg_cnt+1; /* assign out-of-range values */
  180. X#ifdef SUNTOOL
  181. X        if (istool)
  182. X        Clrtoeol(hdr_win, 0, pageful * l_height(DEFAULT), DEFAULT);
  183. X#endif SUNTOOL
  184. X        ++pageful;
  185. X    }
  186. X    }
  187. X#ifdef SUNTOOL
  188. X    if (istool) {
  189. X    if (msg_cnt > screen) {
  190. X        panel_set(next_scr, PANEL_SHOW_ITEM, TRUE, 0);
  191. X        panel_set(prev_scr, PANEL_SHOW_ITEM, TRUE, 0);
  192. X    }
  193. X    mail_status(0);
  194. X    }
  195. X#endif SUNTOOL
  196. X    return 0;
  197. X}
  198. X
  199. X#define NEW 1
  200. X#define ALL 2
  201. X
  202. Xspecl_hdrs(argv, list)
  203. Xchar **argv, list[];
  204. X{
  205. X    u_long    special = 0;
  206. X    int     n = 0;
  207. X
  208. X    while (argv[0][++n])
  209. X    switch(argv[0][n]) {
  210. X        case 'a': special = ALL;
  211. X        when 'n': special = NEW;
  212. X        when 'u': special = UNREAD;
  213. X        when 'o': special = OLD;
  214. X        when 'd': special = DELETE;
  215. X        otherwise: print("choose from n,u,o,d, or a"); return -1;
  216. X    }
  217. X    if (debug)
  218. X    (void) check_flags(special);
  219. X
  220. X    for (n = 0; n < msg_cnt; n++) {
  221. X    /*
  222. X     * First, see if we're looking for NEW messages.
  223. X     * If so, then check to see if the msg is unread and not old.
  224. X     * If special > ALL, then special has a mask of bits describing
  225. X     * the state of the message.
  226. X     */
  227. X    if (ison(glob_flags, IS_PIPE)&& !msg_bit(list, n))
  228. X        continue;
  229. X    if (special == ALL || special == NEW &&
  230. X           (ison(msg[n].m_flags, UNREAD) && isoff(msg[n].m_flags, OLD))) {
  231. X        if (isoff(glob_flags, DO_PIPE))
  232. X        print("%s\n", compose_hdr(n));
  233. X        if (list)
  234. X        set_msg_bit(list, n);
  235. X#ifndef SYSV
  236. X    /*
  237. X     * XENIX compiler can't handle "special" in ison() macro.
  238. X     * It only works if the second argument is a constant!
  239. X     */
  240. X    } else if (special > ALL && ison(msg[n].m_flags, special)) {
  241. X        if (isoff(glob_flags, DO_PIPE))
  242. X        print("%s\n", compose_hdr(n));
  243. X        if (list)
  244. X        set_msg_bit(list, n);
  245. X#endif SYSV
  246. X    } else {
  247. X        if (list)
  248. X        unset_msg_bit(list, n);
  249. X        Debug("msg[%d].m_flags: %d", n, msg[n].m_flags),
  250. X             (void) check_flags(msg[n].m_flags);
  251. X    }
  252. X    }
  253. X    return 0;
  254. X}
  255. X
  256. Xchar *
  257. Xcompose_hdr(cnt)
  258. X{
  259. X    static char buf[256];
  260. X    register char *p, *b, *status;
  261. X    char from[256], subject[256], date[17], lines[6], chars[6], line[256];
  262. X    char to[512], addr[256], name[256];
  263. X
  264. X    /* status of the message */
  265. X    if (ison(msg[cnt].m_flags, DELETE))
  266. X    status = "*";
  267. X    else if (ison(msg[cnt].m_flags, OLD) && ison(msg[cnt].m_flags, UNREAD))
  268. X    status = "U";
  269. X    else if (ison(msg[cnt].m_flags, PRESERVE))
  270. X    status = "P";
  271. X    else if (isoff(msg[cnt].m_flags, UNREAD))
  272. X    status = " ";
  273. X    else
  274. X    status = "N";
  275. X
  276. X    to[0] = from[0] = subject[0] = date[0] = lines[0] = chars[0] =
  277. X    addr[0] = name[0] = line[0] = 0;
  278. X
  279. X    /* who's the message to */
  280. X    if (p = header_field(cnt, "to"))
  281. X    (void) strcpy(to, p);
  282. X
  283. X    /* who the messages is from--
  284. X    %f        From field
  285. X    %a        From address
  286. X    %n        From name
  287. X
  288. X    where %a is anything in angle brackets, or if no angle brackets,
  289. X    anything not in parenthesis, and %n is anything in parenthesis, or if
  290. X    nothing in parenthesis, anything not in angle brackets.
  291. X     */
  292. X    if (!(p = header_field(cnt, "from"))) {
  293. X    /* if all else fails, then get the first token in "From" line */
  294. X    register char *p2;
  295. X    p = ""; /* just in case */
  296. X    if (fseek(tmpf, msg[cnt].m_offset, L_SET) == -1 ||
  297. X        !(p2 = fgets(line, BUFSIZ, tmpf))) {
  298. X        error("fseek in %s (msg %d, folder=%s)", tempfile, cnt+1, mailfile);
  299. X        turnon(glob_flags, READ_ONLY);
  300. X    } else if (!(p = index(p2, ' ')))
  301. X        print("Fudged \"From\" line: %s", p2);
  302. X    else if (p2 = any(++p, " \t"))
  303. X        *p2 = 0;
  304. X    }
  305. X    skipspaces(0);
  306. X    (void) no_newln(p);
  307. X    /* if the "from" line produced the user's login name, then the message is
  308. X     * from the user -- attempt to give more useful information by telling
  309. X     * to whom the message was sent.  This is not possible if the "to" header
  310. X     * failed to get info (which is probably impossible).
  311. X     */
  312. X    if (!strcmp(p, login) && *to)
  313. X    (void) sprintf(from, "TO: %s", to);
  314. X    else
  315. X    (void) strcpy(from, p);
  316. X    /* look for < or (  If <, then whatever is inside goes in addr, and
  317. X     * whatever isn't inside goes in name.  If it's a (, then whatever is
  318. X     * inside goes in name and whatever isn't, goes in addr.  It the same
  319. X     * type of thing, but exclusive of each other.
  320. X     */
  321. X    if (p = any(from, "<(")) {
  322. X    register char *p2, *out, *in;
  323. X    if (*p == '<')
  324. X        out = name, in = addr;
  325. X    else
  326. X        out = addr, in = name;
  327. X
  328. X    (void) strcpy(in, p+1);
  329. X    if (p2 = index(in, (*p == '<')? '>' : ')'))
  330. X        *p2 = 0;
  331. X    /* whatever isn't in <'s gets put in "name". Put p at end of name */
  332. X    if (p - from > 1)
  333. X        (void) strncpy(out, from, p - from), p = out+(p-from);
  334. X    else
  335. X        p = out;
  336. X    if (p2) {
  337. X        /* p2 will be at >, so there will be at least a blank following */
  338. X        while (isspace(*++p2));
  339. X        /* copy remainder of line onto p (end of name) */
  340. X        (void) strcpy(p, p2);
  341. X    }
  342. X    }
  343. X
  344. X    (void) sprintf(lines, "%d", msg[cnt].m_lines);
  345. X    (void) sprintf(chars, "%d", msg[cnt].m_size);
  346. X
  347. X    /* the date */
  348. X    if (p = msg_date(cnt))
  349. X    (void) strcpy(date, date_to_string(p));
  350. X
  351. X    /* and the subject */
  352. X    if (p = header_field(cnt, "subject"))
  353. X    (void) strcpy(subject, p);
  354. X
  355. X    /* now, construct a header */
  356. X    if (!hdr_format) /* this should NEVER be true, but just in case */
  357. X    hdr_format = DEF_HDR_FMT;
  358. X
  359. X    (void) sprintf(buf, "%3.d ", cnt+1);
  360. X    b = buf+4;
  361. X    *b++ = ((cnt == current_msg && !iscurses)? '>': ' ');
  362. X    cnt = 5;
  363. X    for (p = hdr_format; *p; p++)
  364. X    if (*p == '\\')
  365. X        switch (*++p) {
  366. X        case 't':
  367. X            while (cnt % 8)
  368. X            cnt++, *b++ = ' ';
  369. X        when 'n':
  370. X            cnt = 1, *b++ = '\n';
  371. X        otherwise: cnt++, *b++ = *p;
  372. X        }
  373. X    else if (*p == '%') {
  374. X        int buffer_space = 0;
  375. X        register char *p2;
  376. X
  377. X        if (isdigit(*++p))
  378. X        p = my_atoi(p, &buffer_space);
  379. X        switch (*p) {
  380. X        case 'f': p2 = from;
  381. X        when 'a':
  382. X            if (!*(p2 = addr))
  383. X            p2 = from;
  384. X        when 'n':
  385. X            if (!*(p2 = name))
  386. X            p2 = from;
  387. X        when '%': p2 = "%";
  388. X        when 't': p2 = to;
  389. X        when 'd': p2 = date;
  390. X        when 's': p2 = subject;
  391. X        when 'l': p2 = lines;
  392. X        when 'c': p2 = chars;
  393. X        when 'S': p2 = status;
  394. X        otherwise: continue; /* unknown formatting char */
  395. X        }
  396. X        if (!buffer_space)
  397. X        buffer_space = strlen(p2);
  398. X        (void) sprintf(b, "%-*.*s", buffer_space, buffer_space, p2);
  399. X        cnt += buffer_space, b += buffer_space;
  400. X    } else
  401. X        cnt++, *b++ = *p;
  402. X    for (*b-- = 0; isspace(*b); --b)
  403. X    *b = 0;
  404. X    return buf;
  405. X}
  406. X
  407. X/*
  408. X * Using message "n", build a list of recipients that you would mail to if
  409. X * you were to reply to this message.  If "all" is true, then it will take
  410. X * everyone from the To line in addition to the original sender.
  411. X * fix_address() is caled from mail.c, not from here.  There are too many
  412. X * other uses for reply_to to always require reconstruction of return paths.
  413. X * Note that we do NOT deal with Cc paths here either.
  414. X * Check to make sure that we in fact return a legit address (i.e. not blanks
  415. X * or null). If such a case occurs, return login name.  Always pad blank at end.
  416. X */
  417. Xchar *
  418. Xreply_to(n, all, buf)
  419. Xregister char *buf;
  420. X{
  421. X    register char *p = NULL, *p2, *b = buf, *field;
  422. X    char line[256];
  423. X
  424. X    if (field = do_set(set_options, "reply_to_hdr")) {
  425. X    if (!*field)
  426. X        goto From; /* special case -- get the colon-less From line */
  427. X    field = lcase_strcpy(line, field);
  428. X    while (*field) {
  429. X        if (p2 = any(field, " \t,:"))
  430. X        *p2 = 0;
  431. X        if ((p = header_field(n, field)) || !p2)
  432. X        break;
  433. X        else {
  434. X        field = p2+1;
  435. X        while (isspace(*field) || *field == ':' || *field == ',')
  436. X            field++;
  437. X        }
  438. X    }
  439. X    if (!p)
  440. X        print("Warning: message contains no `reply_to_hdr' headers.\n");
  441. X    }
  442. X    if (p || (!p && ((p = header_field(n, "reply-to")) ||
  443. X        (p = header_field(n, "return-path")) ||
  444. X        (p = header_field(n, "from"))))) {
  445. X    skipspaces(0);
  446. X    /* correct reply address is in "<correct-address>" */
  447. X    if (p2 = index(p, '<')) {
  448. X        if (p = index(p2, '>'))
  449. X        *p = 0;
  450. X        p = ++p2;
  451. X    }
  452. X    } else if (!p) {
  453. XFrom:
  454. X    /* if all else fails, then get the first token in "From" line */
  455. X    if (fseek(tmpf, msg[n].m_offset, L_SET) == -1 ||
  456. X        !(p2 = fgets(line, BUFSIZ, tmpf))) {
  457. X        error("fseek in %s (msg %d, folder=%s)", tempfile, n+1, mailfile);
  458. X        turnon(glob_flags, READ_ONLY);
  459. X        return "";
  460. X    }
  461. X    p = index(p2, ' ') + 1;
  462. X    }
  463. X    /* find the first space and plug a null */
  464. X    if (p2 = any(p, " \t\n"))
  465. X    *p2 = 0;
  466. X    b += Strcpy(buf, p);
  467. X
  468. X    /*
  469. X     * if `all' is true, append everyone on the "To:" line.
  470. X     * cc_to(), called separately, will catch the cc's
  471. X     */
  472. X    if (all && (p = header_field(n, "to")) && *p)
  473. X    (void) sprintf(b, " %s", p);
  474. X    rm_cmts_in_addr(buf);
  475. X    for (p = buf; isspace(*p); p++);
  476. X    if (!*p)
  477. X    (void) strcpy(buf, login);
  478. X    return strcat(buf, " ");
  479. X}
  480. X
  481. Xchar *
  482. Xsubject_to(n, buf)
  483. Xregister char *buf;
  484. X{
  485. X    register char *p;
  486. X    buf[0] = 0; /* make sure it's already null terminated */
  487. X    if (!(p = header_field(n, "subject")))
  488. X    return NULL;
  489. X    if (strncmp(p, "Re:", 3))
  490. X    (void) strcpy(buf, "Re: ");
  491. X    return strcat(buf, p);
  492. X}
  493. X
  494. Xchar *
  495. Xcc_to(n, buf)
  496. Xregister char *buf;
  497. X{
  498. X    register char *p;
  499. X    buf[0] = 0; /* make sure it's already null terminated */
  500. X    if (!(p = header_field(n, "cc")))
  501. X    return NULL;
  502. X    rm_cmts_in_addr(p);
  503. X    return strcpy(buf, p);
  504. X}
  505. X
  506. X/*
  507. X * fix addresses according to the sender's address.  If he's on a remote
  508. X * machine, chances are that the addresses of everyone else he mailed to
  509. X * are addresses from his machine.  Reconstruct those addresses to route
  510. X * thru the senders machine first.
  511. X */
  512. Xfix_addresses(to, cc)
  513. Xchar *to, *cc;
  514. X{
  515. X    int   to_argc, cc_argc, cnt;
  516. X    char  **to_argv, **cc_argv, pre_path[128], *p, c;
  517. X    char  **new_to, **new_cc, **calloc(), buf[256];
  518. X
  519. X    pre_path[0] = 0;
  520. X    if (!(to_argv = mk_argv(to, &to_argc, 0)))
  521. X    return;   /* what can we do?  Just return unchanged To and Cc lists */
  522. X    cc_argv = mk_argv(cc, &cc_argc, 0);  /* the cc list may be empty */
  523. X    if (cc_argc == 0 && to_argc == 1)
  524. X    return;   /* there's only one reciepient, nothing to alter */
  525. X
  526. X    if (p = any(to_argv[0], "!=")) {
  527. X    char *p2;
  528. X    while (p2 = any(++p, "!="))
  529. X        p = p2;
  530. X    c = *p, *p = 0;
  531. X    (void) strcpy(pre_path, to_argv[0]);
  532. X    *p = c;
  533. X    for (cnt = 0; cnt < MAX_HOST_NAMES && ourname[cnt]; cnt++)
  534. X        if (!strcmp(pre_path, ourname[cnt])) {
  535. X        *pre_path = 0;
  536. X        break;
  537. X        }
  538. X    }
  539. X
  540. X    if (!(new_to = calloc((unsigned)(to_argc+1), sizeof (char *))) ||
  541. X    !(new_cc = calloc((unsigned)(cc_argc+1), sizeof (char *)))) {
  542. X    error("malloc in fix_headers");
  543. X    return;
  544. X    }
  545. X    /* this is the original sender */
  546. X    strdup(new_to[0], to_argv[0]);
  547. X
  548. X    /* now modify the addresses to be routed thru the sender's adderess */
  549. X    for (cnt = 1; cnt < to_argc; cnt++) {
  550. X    if (p = index(to_argv[cnt], ','))
  551. X        *p = 0;
  552. X    Debug("Changing \"%s\" to ", to_argv[cnt]);
  553. X    (void) sprintf(buf, "%s%s", pre_path, to_argv[cnt]);
  554. X    strdup(new_to[cnt], buf);
  555. X    Debug("\"%s\"\n", new_to[cnt]);
  556. X    }
  557. X    for (cnt = 0; cnt < cc_argc; cnt++) {
  558. X    Debug("Changing \"%s\" to ", cc_argv[cnt]);
  559. X    if (p = index(cc_argv[cnt], ','))
  560. X        *p = 0;
  561. X    (void) sprintf(buf, "%s%s", pre_path, cc_argv[cnt]);
  562. X    strdup(new_cc[cnt], buf);
  563. X    Debug("\"%s\"\n", new_cc[cnt]);
  564. X    }
  565. X    (void) argv_to_string(to, new_to);
  566. X    (void) argv_to_string(cc, new_cc);
  567. X    free_vec(to_argv);
  568. X    free_vec(cc_argv);
  569. X    free_vec(new_to);
  570. X    free_vec(new_cc);
  571. X}
  572. X
  573. X/*
  574. X * pass a string describing header like, "Subject: ", current value, and
  575. X * whether or not to prompt for it or to just post the information.
  576. X * If do_prompt is true, "type in" the current value so user can either
  577. X * modify it, erase it, or add to it.
  578. X */
  579. Xchar *
  580. Xset_header(str, curstr, do_prompt)
  581. Xregister char *str, *curstr;
  582. X{
  583. X    static char       buf[BUFSIZ];
  584. X    int        offset = 0;
  585. X    register char  *p = curstr;
  586. X
  587. X    buf[0] = 0;
  588. X    wprint(str);
  589. X    fflush(stdout);         /* force str curstr */
  590. X    if (do_prompt) {
  591. X    if (curstr)
  592. X        for (p = curstr; *p; p++)
  593. X#ifdef SUNTOOL
  594. X        if (istool)
  595. X            rite(*p); /* mimics typing for the tool */
  596. X        else
  597. X#endif /* SUNTOOL */
  598. X        if (isoff(glob_flags, ECHO_FLAG))
  599. X            fputc((buf[offset++] = *p), stdout);
  600. X        else
  601. X#ifdef TIOCSTI
  602. X            if (ioctl(0, TIOCSTI, p) == -1) {
  603. X            error("ioctl: TIOCSTI");
  604. X            wprint("You must retype the entire line.\n%s", str);
  605. X            break;
  606. X            }
  607. X#else
  608. X                {
  609. X            wprint("WARNING: -e flag! Type the line over.\n%s", str);
  610. X            break;
  611. X        }
  612. X#endif TIOCSTI
  613. X
  614. X    if (istool)
  615. X        return NULL;
  616. X    if (Getstr(buf, BUFSIZ, offset) == -1)
  617. X        buf[0] = 0;
  618. X    } else
  619. X    puts(strcpy(buf, curstr));
  620. X    if (debug > 1)
  621. X    print("returning (%s) from set_header\n", buf);
  622. X    return buf;
  623. X}
  624. X
  625. X/*
  626. X * rm_cmts_in_addr() removes the comment lines in addresses that result from
  627. X * sendmail or other mailers which append the user's "real name" on the
  628. X * from lines.  Comments are in parens.
  629. X * `take_me_off' takes occurences of login out of a list of recipients
  630. X * if the variable "metoo" is set.  Some say that "metoo" is supposed to
  631. X * pass the -m flag along to sendmail, but not everyone runs sendmail :-)
  632. X *
  633. X * First expand a possible alias. Note that same string returns if not aliased.
  634. X * strip off host from login name (considers user@host, host!user and so on)
  635. X * if (user == ourlogin)
  636. X *    match host with _this_ host, or
  637. X *    match host with alternate hosts (alternate hostname, * matches all cases)
  638. X *    if matched, then remove name from list.
  639. X * ignore parenthesized names (those are comments ignored by "correct" mailers)
  640. X */
  641. Xrm_cmts_in_addr(p)
  642. Xregister char *p;
  643. X{
  644. X    char buf[BUFSIZ], *start = p, *cmnt;
  645. X    register char **argv;
  646. X    int cnt, argc, x = 0, take_me_off = !do_set(set_options, "metoo");
  647. X    int in_cmnt = FALSE, i;
  648. X
  649. X    if (!(argv = mk_argv(p, &argc, 0)))
  650. X    return;
  651. X    for (cnt = 0; cnt < argc; cnt = x+1) {
  652. X    /* comments are in parens, as in: "argv (Dan Heller)" */
  653. X    if ((cmnt = any(argv[cnt], "()")) || in_cmnt) {
  654. X        x++;
  655. X        if (cmnt && *cmnt != ')')
  656. X        in_cmnt = TRUE;
  657. X        else if (cmnt && *cmnt == ')')
  658. X        in_cmnt = FALSE; /* else, unchange cmnt flag */
  659. X        /* if the previous argument was deleted, then delete this one
  660. X         * example, we are "user" and our host is "host" take off:
  661. X         * list ... user@host (firstname lastname) more users...
  662. X         * "user@host" "(Firstname" "Last name)"
  663. X         */
  664. X        xfree(argv[cnt]), argv[cnt] = "";
  665. X        continue;
  666. X    }
  667. X    (void) strcpy(buf, argv[x = cnt]);
  668. X    /* example: "Dan Heller <argv>" -- real address is in angle brackets
  669. X     * delete the angle brackets.  Potential bug: the name is still in
  670. X     * the address.. result might be: "Dan Heller argv"
  671. X     */
  672. X    if (*buf == '<') {
  673. X        while (!(p = index(argv[x], '>')))
  674. X        if (++x == argc)
  675. X            break;
  676. X        else
  677. X            (void) strcat(buf, argv[x]);
  678. X        if (!p)  /* this one is in error, but parse the rest anyway */
  679. X        continue;
  680. X        if (p = index(buf, '>'))
  681. X        *p = 0; /* play with buf, not argv[]! */
  682. X    }
  683. X
  684. X    /* if we're removing ourselves from the list, see if we're on it */
  685. X    if (!take_me_off || !chk_two_lists(login, buf, "!@%="))
  686. X        continue;
  687. X
  688. X    /* we must be on the list -- see if the hostnames match alternates
  689. X     * first match our current host if a host was even given.
  690. X     * Bug: if a login name is a subset (or a complete) hostname, then
  691. X     * incorrect results may occur.
  692. X     */
  693. X    if (any(buf, "!@%=")) {
  694. X        for (i = 0; i < MAX_HOST_NAMES && ourname[i]; i++)
  695. X        if (chk_two_lists(buf, ourname[i], "!@%="))
  696. X            break;
  697. X        /* If the hostname in the address is one of our hostnames,
  698. X         * remove this address.  Else, see if the alternates hostnames
  699. X         * are in the address.
  700. X         */
  701. X        if ((i == MAX_HOST_NAMES || !ourname[i]) &&
  702. X        (!(p = do_set(set_options, "alternates")) || *p != '*' &&
  703. X         !chk_two_lists(buf, p, "!@%= \t,")))
  704. X            continue;
  705. X    }
  706. X    /* all's well that ends well -- take us off the list */
  707. X    xfree(argv[cnt]), argv[cnt] = "";
  708. X    }
  709. X    (void) argv_to_string(start, argv);
  710. X    free_vec(argv);
  711. X}
  712. X
  713. X/*
  714. X * improve uucp paths by looking at the name of each host listed in the
  715. X * path given.
  716. X *    sun!island!pixar!island!argv
  717. X * It's a legal address, but redundant. Also, if we know we talk to particular
  718. X * hosts via uucp, then we can just start with that host and disregard the
  719. X * rest of the line.  So, first get the known hosts and save them. Then start
  720. X * at the end of the original path (at the last ! found), and move backwards
  721. X * saving each hostname.  If we get to a host that we know about, stop there
  722. X * and use that address.  If we get to a host we've already seen, then
  723. X * delete it and all the hosts since then until the first occurance of that
  724. X * hostname.  When we get to the beginning, the address will be complete.
  725. X *
  726. X * return all results into the original buffer passed to us.  Since we can
  727. X * at worst not touch the path (shorten it if anything), we know we're not
  728. X * going to overrun the buffer.
  729. X */
  730. X
  731. X#define go_back_to_bang() for (--p; p > start && *p != '!'; p--)
  732. X
  733. Ximprove_uucp_paths(original)
  734. Xregister char *original;
  735. X{
  736. X    char       hostnames[32][64], buf[BUFSIZ], *knowns, *end;
  737. X    register char *p, *recipient, *start = original, *b = buf, c;
  738. X    int           saved_hosts, i;
  739. X
  740. X    if (!original || !*original)
  741. X    return;
  742. X
  743. X    knowns = do_set(set_options, "known_hosts");
  744. X
  745. X    while ((end = any(start, " \t,")) || *start) {
  746. X    saved_hosts = 0;
  747. X    if (!end)
  748. X        p = start + strlen(start);
  749. X    else
  750. X        p = end; /* set p to the "end" cuz p moves. start will equal end */
  751. X    c = *p, *p = 0; /* save the char we're nulling out (separating addrs) */
  752. X    go_back_to_bang();
  753. X    if (p == start)
  754. X        b += Strcpy(b, start), recipient = NULL;
  755. X    else {
  756. X        recipient = p+1;
  757. X        while (p > start) {
  758. X        /* null remainder of string to save the hostname */
  759. X        *p = 0;
  760. X        go_back_to_bang();
  761. X        /* if p is not at the start, move it forward past the '!' */
  762. X        if (p != start)
  763. X            ++p;
  764. X#ifndef SYSV
  765. X        /* next host on the list is ourselves, ignore preceding names */
  766. X        for (i = 0; i < MAX_HOST_NAMES && ourname[i]; i++)
  767. X            if (!strcmp(p, ourname[i]))
  768. X            saved_hosts = 0;
  769. X#endif SYSV
  770. X        for (i = 0; i < saved_hosts; i++)
  771. X            if (!strcmp(hostnames[i], p))
  772. X               saved_hosts = i;
  773. X        (void) strcpy(hostnames[saved_hosts++], p);
  774. X        if (saved_hosts == 32) {
  775. X            print("Too many hosts in uucp path! Address not fixed.\n");
  776. X            return; /* original buffer is unchanged */
  777. X        }
  778. X        /* If we know that we call this host, break */
  779. X        if (p == start || knowns && chk_two_lists(p, knowns, " ,\t"))
  780. X            break;
  781. X        --p; /* move p back onto the '!'; it != start */
  782. X        }
  783. X    }
  784. X    while (saved_hosts-- > 0)
  785. X        b += strlen(sprintf(b, "%s!", hostnames[saved_hosts]));
  786. X    if (recipient) {
  787. X        /* if there were no saved_hosts, add a ! */
  788. X        if (*(b-1) != '!')
  789. X        *b++ = '!';
  790. X        b += Strcpy(b, recipient);
  791. X    }
  792. X    *b++ = c;
  793. X    if (!end)
  794. X        break;
  795. X    start = end + 1;
  796. X    if (isspace(*start)) {
  797. X        *b++ = ' ';
  798. X        while (isspace(*start))
  799. X        start++;
  800. X    }
  801. X    }
  802. X    *b = 0;
  803. X    (void) strcpy(original, buf);
  804. X}
  805. END_OF_FILE
  806. if test 23014 -ne `wc -c <'hdrs.c'`; then
  807.     echo shar: \"'hdrs.c'\" unpacked with wrong size!
  808. fi
  809. # end of 'hdrs.c'
  810. fi
  811. if test -f 'tool_help' -a "${1}" != "-c" ; then 
  812.   echo shar: Will not clobber existing file \"'tool_help'\"
  813. else
  814. echo shar: Extracting \"'tool_help'\" \(23232 characters\)
  815. sed "s/^X//" >'tool_help' <<'END_OF_FILE'
  816. X@(#)tool_help    (c) copyright 10/18/86 (Dan Heller)
  817. X
  818. X%general%
  819. X
  820. X      IF ALL ELSE FAILS, READ THE DIRECTIONS!
  821. X
  822. XThis famous  quote applies here more  than ever. If
  823. Xyou are unfamiliar with this mailtool, get yourself
  824. Xacquainted with it by choosing  HELP options in all
  825. Xmenu items. If you get frustrated or confused about
  826. Xhow to use or run a command, or if you want to know
  827. Xhow something  works or get to know quick shortcuts
  828. Xin achieving tasks, it is  advisable to look at the
  829. XHelp option available with the item.
  830. X
  831. XSince there  are many different  options to some of
  832. Xthe commands in  mailtool, explanation  of  options
  833. Xfor the commands can be found by choosing the RIGHT
  834. Xmouse button over an item. This will display a menu
  835. Xof options for the command. One of the menu options
  836. Xwill almost always be a Help option.
  837. X
  838. XGive yourself a head start, try selecting this same
  839. Xitem with the RIGHT mouse button.  When you do, you
  840. Xwill given some more help topics to choose from.
  841. X%%
  842. X
  843. X%help%
  844. XHelp was designed for users to get  help from anywhere on  the mailtool
  845. Xwindow.  The RIGHT mouse button may be selected on virtually every -
  846. X on any of the windows on the entire tool and  a menu will appear.
  847. XThe last item in almost  every menu  is a "help" item.  You will get an
  848. Xappropriate help message describing what you can do at the position you
  849. Xare in on the mailtool window.
  850. X
  851. XIf a help  message isn't much help, it may be more helpful to reference
  852. Xa different help item which  describes in more detail  what you want to
  853. Xknow.  For example, reading the help for  "folder" will help you better
  854. Xunderstand  the method in  which mail messages are stored than it would
  855. Xif you had read the help message for "save" first.
  856. X%%
  857. X
  858. X%mouse%
  859. XThe mouse is an image (cursor) which moves across the screen. Its
  860. Xposition indicates which window is to receive input when you type
  861. Xor click a mouse button.
  862. X
  863. XThe mouse may take upon  different images which  indicate various
  864. Xthings. When the image looks like a "coffee cup",  Mushtool is in
  865. Xthe process of doing something,  like sending mail, or reading in
  866. Xnew mail.  In this event, you should wait till the cursor returns
  867. Xto its normal state before attempting to do anything else. Go get
  868. Xsome coffee.
  869. X
  870. XWhen the mouse looks like a pair of glasses, you are reading mail
  871. Xand when it looks like a pencil, you  are editing a letter.  When
  872. Xin the  Header Window, the cursor will look like the mouse device
  873. Xthat you hold  with the buttons  flashing on and off.  This is to
  874. Xremind  you that you  can use each button  to do different tasks.
  875. X
  876. XIn one window, the Main Panel Window, the cursor image looks like
  877. Xan envelope.  Placing the cursor over "Panel Items" and selecting
  878. Xthe LEFT button will do that command.  Selecting the RIGHT  mouse
  879. Xbutton will give a menu of options to choose from. In most cases,
  880. XHelp is  available and the end of each menu list to help you with
  881. Xthe proper use of Panel Items.
  882. X
  883. XWhen you are asked a yes or no question, choosing either the LEFT
  884. Xor RIGHT mouse buttons is the same as typing "y" or "n".
  885. X%%
  886. X
  887. X%respond%
  888. XThis item responds to mail in 4 ways.
  889. XIn all cases, at least one recipient of your message will be the
  890. Xsender of the message you are responding to. If a subject was in
  891. Xthe author's letter, then it will be used as your subject.
  892. X
  893. XThe first and most used method of response is to the author of the
  894. Xmessage only.  Selecting this item with the LEFT mouse button will
  895. Xuse this method for responding to mail.
  896. X
  897. XIf you want to include a copy of the author's message, then choose
  898. Xthe menu item which  says to include the message.  If you wish for
  899. Xall the recipients of the message to receive a copy of your reply,
  900. Xthen choosing the third item will include them.
  901. X
  902. XThe fourth menu item will mail to the author and everyone listed on
  903. Xthe To and Cc lines of the message, and include the message you are
  904. Xresponding to in your text.
  905. X
  906. XIn such cases where you include the message you are responding to,
  907. Xthe included message will be indented by "> " to identify it from
  908. Xyour message. If you would like to have a string other than the
  909. Xdefault used, then set the appropriate option to whatever you would
  910. Xprefer by selecting the "Opts" item, moving the mouse on top of the
  911. Xstring, "indent-str", selecting the LEFT mouse button and typing the
  912. Xdesired string.
  913. X%%
  914. X
  915. X%menu_respond%
  916. XWhen you respond to a message using the menu item, you respond to the author
  917. Xof the message only. Since there are  more ways to respond to a message, you
  918. Xmay want to choose the  Main Panel Window's Reply item. This item also gives
  919. Xfar more extensive help than described here.
  920. X%%
  921. X
  922. X%menu_delete%
  923. XThis menu may delete or undelete
  924. Xwhichever  message you happen to
  925. Xhave the cursor sitting on.  For
  926. Xdeleting messages  only, you can
  927. Xsimply  select the  MIDDLE mouse
  928. Xbutton  over the message  header
  929. Xyou would like deleted.
  930. X
  931. XFor extensive information on -
  932. X or undeletion of messages
  933. Xtry the the  Main Panel Window's
  934. Xitem for Delete.
  935. X%%
  936. X
  937. X%delete%
  938. XYou may  delete or undelete  messages with this item.
  939. XWhen using the LEFT mouse button, you will delete the
  940. Xcurrent message (HIGHLIGHTED in the headers' window).
  941. XOtherwise, you may delete or undelete all messages by
  942. Xselecting the appropriate menu item.
  943. X
  944. XYou may  delete or undelete a  "range" of messages by
  945. Xtyping the range in the  Header Window  and selecting
  946. Xthe appropriate menu item (delete/undelete range).
  947. X
  948. XFor help on valid  message ranges, select the menu in
  949. Xthe area  marked "range" in the  Header Panel Window.
  950. X%%
  951. X
  952. X%folder%
  953. XThis item changes your "folder" -- which is  a place to keep all your
  954. Xindividual messages. Usually, if you are a heavy mail user, you would
  955. Xorganize your mail in such a way in which related mail would be saved
  956. Xtogether in one folder.   You create folders simply by saving mail to
  957. Xa filename.  Additional mail can  be saved to those files in the same
  958. Xway.  To manipulate messages in folders,  you "change folders" to the
  959. Xfolder you wish to access using the folder item.   Since it may occur
  960. Xthat you switch  back and forth  between two folders, you may use the
  961. Xprevious  folder menu item which updates changes  made to the current
  962. Xfolder and  changes your  folder to the one previous to  the current.
  963. X
  964. XYou may also select  the exact name of the  folder you wish to access
  965. Xby selecting  the left  mouse button on the "folder"  item and TYPING
  966. Xthe exact  name of the folder  you wish to access.  The "pathname" to
  967. Xthe folder may start with a tilde (~) indicating your home directory.
  968. XOr, it may  contain a plus sign before the  name indicating your Mail
  969. Xdirectory (+reports, for example).  Alternatively, you  can type  '%'
  970. Xto access your system Mailbox, the place where all your mail is first
  971. Xdelivered.  And finally, you can type '#' to indicate  the previously
  972. Xaccessed folder.  See the help for "chdir" for more information.
  973. X%%
  974. X
  975. X%chdir%
  976. XThis is used to just change working directories.
  977. XYour  working directory contains files and other
  978. Xdirectories.  Files can be "mail folders"  which
  979. Xcontain mail  messages.  You can change to other
  980. Xdirectories using some of the following methods:
  981. X
  982. XYou can select from the menu, HOME or Mail, which
  983. Xare your home and default mail directories. Or,
  984. Xselect the left mouse button and TYPE in the name
  985. Xof the directory you would like to change to.
  986. X
  987. XTyped names may have the following syntax:
  988. X
  989. X~[/subpath]   will change to your home directory and
  990. X              a path below that, if specified. Also,
  991. X              you can specify other users: ~username
  992. X+[subpath]    This is your default Mail directory.
  993. X%%
  994. X
  995. X%save%
  996. XYou may save messages in  two ways. The most commonly used method is to
  997. Xsave messages to  your mailbox folder  ("mbox") in your home directory.
  998. XIf you use mail very frequently and save large amounts of mail, you can
  999. Xsave messages to other folders for better organization.
  1000. X
  1001. XUsually, when messages are saved, mailtool  marks them for deletion for
  1002. Xthe next update.  If you don't want to have saved messages deleted, you
  1003. Xmust undelete them.
  1004. X
  1005. XThere is a text item  in the Main Panel Window which allows you to type
  1006. Xthe  name of the file to save a message.  Select the  LEFT mouse button
  1007. Xover the "Save" item, and type the filename and hit return. If there is
  1008. Xno filename specified, then messages are saved to your mbox file.
  1009. X
  1010. XYou can specify a range, or group of messages to save by typing a range
  1011. Xin the  Header Panel Window.
  1012. X
  1013. XFor additional information, see the help option for Folders.
  1014. X%%
  1015. X
  1016. X%quit%
  1017. XThere are various ways in which you may be finished with mailtool.
  1018. XThe most commonly used method  is to simply "close" the tool to an
  1019. Xiconic form. This means that you haven't really quit, but you have
  1020. Xmerely put it on "hold" till later.  It will become an icon on the
  1021. Xside or corner of the screen and appear to sit and do nothing.  To
  1022. Xclose the tool to icon form, there are two methods which have will
  1023. Xhave two different effects.
  1024. X
  1025. XThe first method is to select  this panel item with the left mouse
  1026. Xbutton.  This  will update your current  folder (deleting messages
  1027. Xmarked for deletion) and close the tool.  The second method  is to
  1028. Xuse the tool manager around the perimeter of the window and select
  1029. X"close".  This will close the tool without updating your mailfile.
  1030. X
  1031. XWhenever the mailtool is  in the "closed"  state, it  periodically
  1032. Xchecks your mail and updates your folder with the  new mail. While
  1033. Xmailtool is in iconic form, it will display the number of messages
  1034. Xyou have in the current folder.
  1035. X
  1036. XThere are two equally similar methods of exiting  mailtool, rather
  1037. Xthan just closing to an icon:  you may select the second menu item
  1038. Xin the menu given by this panel item or you may use the tool mana-
  1039. X "quit" item.
  1040. X
  1041. XUsing the tool manager's quit will exit the tool without updating
  1042. Xyour folder whereas the panel item's menu selection will have the
  1043. Xmailtool prompt you whether to update the current folder or not.
  1044. X%%
  1045. X
  1046. X%help_menu_help_msg%
  1047. XSelecting an item within this menu will
  1048. Xgive you help on that item. If you want
  1049. Xto execute the action, choose the other
  1050. Xmenu by placing the mouse over the menu
  1051. XBEHIND this menu, continue to keep your
  1052. XRIGHT mouse button depressed and select
  1053. Xthe LEFT mouse button  over the menu on
  1054. Xthe bottom and select that action.
  1055. X%%
  1056. X
  1057. X%msg_menu%
  1058. XWhen given menu in the Header Window, you will have a choice
  1059. Xof actions to take.  The message may not be the current one,
  1060. Xit may be  any message that  appears in  the Headers Window.
  1061. XThe "title" of the menu  will indicate which message you are
  1062. Xreferring to.
  1063. X
  1064. XAt this point, you can select actions to take. You can Read,
  1065. XDelete, Undelete, Save, Reply to, or Print messages. Most of
  1066. Xthese are self explanatory, but if you need help with one of
  1067. Xthese, place the  mouse over the menu BEHIND the given menu,
  1068. Xcontinue to have the RIGHT mouse button depressed and select
  1069. Xthe LEFT mouse button over the Help Menu.
  1070. X
  1071. XThis action toggles the menus such  that you can change back
  1072. Xand forth between these menus. The menu you are on will tell
  1073. Xwhich action to take on that message.  In  either case,  you
  1074. Xplace the mouse over the action to take, and,  if you are on
  1075. Xthe help menu, help will be given regarding that  particular
  1076. Xaction. If not in  the help menu,  then that specific action
  1077. Xwill actually be taken.
  1078. X%%
  1079. X
  1080. X%edit%
  1081. XChoosing this item with the LEFT mouse button in
  1082. Xthe Main Panel Window or in the Menu item will
  1083. Xallow you to access a full-screen editor. The
  1084. Xeditor which you will use is indicated when you
  1085. Xselect the "opts" item in the Main Panel Window.
  1086. X
  1087. XWhile you are typing a letter, you can specify
  1088. Xexplicitly which editor to use by typing (on a
  1089. Xline by itself) "~v editor". Type "~?" on a line
  1090. Xby itself while typing to see a list of valid
  1091. X"~commands".
  1092. X
  1093. XUpon exiting the editor, you can continue typing
  1094. Xand even reenter the editor if you like in the
  1095. Xsame manner.
  1096. X%%
  1097. X
  1098. X%update%
  1099. XThis item will update the current folder you are using.
  1100. XChanges are updated to the folder; that is, deleted mail
  1101. Xis removed and all other mail is copied back to the folder
  1102. Xunless otherwise specified. See the help in "folder" for
  1103. Xmore information on folders.
  1104. X
  1105. XIf new mail has arrived, it will incorporate it. Otherwise,
  1106. Xnew mail is incorporated every two minutes or so, if some
  1107. Xcomes in.
  1108. X%%
  1109. X
  1110. X%headers%
  1111. XThe message headers are displayed in their own separate window.
  1112. XThe "current" message is usually displayed in either BOLD or
  1113. XREVERSE text. This "highlighted" message is the one which is
  1114. Xdisplayed at the bottom, larger window. In the message window,
  1115. Xeach message is displayed in the following format:
  1116. Xthe message number is displayed first; if it is the "current"
  1117. Xmessage, then there is a '>' sign.
  1118. XThe next character is the 'status' character:
  1119. X    'N' -- New (and unread)
  1120. X    'U' -- not new, but still Unread
  1121. X    '*' -- delete messages (set show_deleted)
  1122. X    'P' -- preserve in spoolfile.
  1123. X    'O' -- Old message which has also been Read.
  1124. XIf there is just a space (no character), the message is new, but
  1125. Xyou've already read it. You should explicitly save or delete these.
  1126. X
  1127. XFollowing that is the Author of the message and/or all or part of
  1128. Xhis network address and login name.  Following that is the number
  1129. Xof lines the message is. In quotes is all or part of the "Subject"
  1130. X(if one was specified).
  1131. X
  1132. XTo read a message, select either the READ item in the main panel
  1133. Xsubwindow or move the mouse over the message header you want to read
  1134. Xand press the LEFT mouse button. Or, the MIDDLE mouse button will
  1135. Xdelete that message. Choosing the RIGHT mouse button will give you
  1136. Xa menu of things to do then. Included in the menu, is a help item
  1137. Xwhich describes the selections in the menu.
  1138. X%%
  1139. X
  1140. X%preserve%
  1141. XUsually, after you read mail and you "update" or quit  mailtool, unread
  1142. Xmessages are copied back into your system mailbox, deleted messages are
  1143. Xremoved, and messages which have been read but not deleted are saved in
  1144. Xyour "mbox" file.  Specifying "hold" prevents this from ever happening,
  1145. Xbut you can mark specific messages to be held in your system mailbox by
  1146. Xpreserving them.
  1147. X%%
  1148. X
  1149. X%compose%
  1150. XWhen you start to compose a letter for mailing,
  1151. Xyou will be prompted  for the login name(s), of
  1152. Xwhom  you want to mail, the (optional)  subject
  1153. Xof the message, and an  optional list of carbon
  1154. Xcopy recipients.  This is an additional list of
  1155. Xlogin names  who will be  mailed copies of your
  1156. Xmessage.
  1157. X
  1158. XAfter that, anything you type will be added to
  1159. Xyour  message.  If you select the  RIGHT mouse
  1160. Xbutton in the window in  which you are type to
  1161. Xget a menu of  things to do.  You may enter an
  1162. Xeditor if your message needs to be modified in
  1163. Xmore detail.
  1164. X
  1165. XWhen you're through with your message, you can
  1166. Xsend it by typing (on a line by itself) "." or
  1167. X^D.  Or, you can select  the Send item  in the
  1168. XMain Panel Window  and your mail will be sent.
  1169. XYou cannot send mail while still in an editor;
  1170. Xyou must exit the editor first.
  1171. X
  1172. XIf you have the option "autoedit" set, you are
  1173. Xautomatically put into an editor when you want
  1174. Xto compose or  whenever you reply to a letter.
  1175. XIn this case, whenever  you're through editing
  1176. Xthe letter, you will be put back into the main
  1177. Xediting mode  where you terminate and send the
  1178. Xletter using any of the above methods.
  1179. X%%
  1180. X
  1181. X%next%
  1182. XYou can page through all your messages by selecting  "Next" after reading
  1183. Xeach message. The same effect is gotten when you select the "Delete" item
  1184. Xwhen the option,  "autoprint" is set to be true  (see "opts") except that
  1185. Xthe current message is deleted before the next one is displayed. Deleting
  1186. Xmail which is  not important  helps the  efficiency of mailtool and reduces
  1187. Xunnecessary use of system resources.
  1188. X
  1189. XIn the Header Window, you will notice the cursor looks like the mouse you
  1190. Xuse.  The blinking buttons on the mouse image remind you that you can use
  1191. Xany of the  three buttons  at any  time.  When you  move the mouse over a
  1192. Xmessage and choose a button, the message under the  mouse is going to be
  1193. Xthe one affected.  Choosing left button will read the message, the middle
  1194. Xbutton will delete it, and the right button will give you a menu.
  1195. X%%
  1196. X
  1197. X%aliases%
  1198. XAliases are used as a method of mailing to users with long addresses using
  1199. Xshort names. For example, if you wanted to mail to
  1200. X    argv@spam.istc.sri.com
  1201. Xbut didn't want to type that all the time, then you could make an alias by
  1202. Xselecting the alias menu item that specifies "adding alias" and then TYPE:
  1203. X    Dan argv@spam.istc.sri.com
  1204. XIf you want to mail to a list of people and do so frequently enough to want
  1205. Xan alias name for the whole list, then  you would type something like this:
  1206. X    project-group fred mary bob@foo-bar herb sly@baz.bitnet
  1207. X
  1208. XTo mail to an "alias" you would compose a letter and address the letter:
  1209. X
  1210. XTo: Dan
  1211. XSubject: Alias example
  1212. XCc: project-group
  1213. X(rest of letter)
  1214. X%%
  1215. X
  1216. X%alts%
  1217. X"Alternates" are alternate names for YOU.  In messages you
  1218. Xreceive, your account will appear on the "To" or "Cc" list.
  1219. XWhen you REPLY to those messages, mailtool will construct
  1220. Xa message header for your letter which will contain the To
  1221. Xand Cc lists of recipients from the original message. You
  1222. Xwould probably want your name taken off the list so you do
  1223. Xnot mail yourself a copy of your own message. If you have
  1224. Xother account names or accounts on other machines, you can
  1225. Xlet mailtool know what those mail addresses are so they can
  1226. Xbe removed from the lists as well.
  1227. X
  1228. XNote, that if YOU add your name MANUALLY (type it yourself)
  1229. Xto either of the lists, it will not be removed.
  1230. X
  1231. XYou can set such a list in your .mailrc file in your home
  1232. Xdirectory by adding the line:
  1233. X
  1234. Xalts hostname1 hostname2 ...
  1235. X
  1236. XIf you prefer to not have your name removed from lists when
  1237. Xresponding to mail, set the option "metoo" and this prevents
  1238. Xthe need for alternates and your name will never be removed.
  1239. X%%
  1240. X
  1241. X%opts%
  1242. XTo set or unset options and their values, move the mouse over
  1243. Xthe option of your choice and select the LEFT button to toggle
  1244. Xtrue/false values. If an option requires a string value, you
  1245. Xmust type the value, so select the LEFT button to reference
  1246. Xthe option, and then type away.  Use a Carriage Return to enter
  1247. Xthe final value for the option.
  1248. X
  1249. XYou may select the RIGHT mouse button anywhere in the window
  1250. Xto give a menu which consists of saving options permanently,
  1251. Xreading in previous settings (from ~/.mailrc), and other things.
  1252. X%%
  1253. X
  1254. X%ignore%
  1255. XWhen reading mail, the message "headers" may clutter up the
  1256. Xwindow with information you are not interested in.  For
  1257. Xexample, you may not be interested in the "Received" or
  1258. X"Message-Id" field of the mail message. You would find that
  1259. Xin time, it will become annoying to see these uninteresting
  1260. Xmessage headers.
  1261. X
  1262. XYou can specify which message headers should not be shown,
  1263. Xthus shortening the appearance of the length of the message.
  1264. X
  1265. XTypical settings:
  1266. X    Received
  1267. X    Message-Id
  1268. X    Status
  1269. X%%
  1270. X
  1271. X%printer%
  1272. XThis item will send the current message, or the message specified on the
  1273. Xmenu header, to the printer. The printer used is given by the "printer"
  1274. Xoption (see opts in Main Panel Window). To specify a different printer,
  1275. Xchange the printer option by selecting the item "Opts" in the Main Panel
  1276. XWindow, moving the mouse over the Printer option, selecting the LEFT
  1277. Xmouse button and typing the name of the printer which you'd like to use.
  1278. X
  1279. XBe sure to set this option before printing because the DEFAULT option may
  1280. Xnot be what you want.
  1281. X
  1282. XYou can print messages that are NOT the current message by moving the
  1283. Xmouse into the Header Window and selecting the RIGHT mouse button on top
  1284. Xof the message you want to print and selecting the PRINT menu option.
  1285. X%%
  1286. X
  1287. X%windows%
  1288. X"Windows" are the boxes which contain items, text, or graphic
  1289. Ximages.  There are two "panel" windows. A panel window is one
  1290. Xwhich contains items,  which are the little boxes  with words
  1291. Xthat you can place the mouse over and click the left or mouse
  1292. Xbutton.
  1293. X
  1294. XEach  window has a separate  function for different purposes.
  1295. XStarting at the top of the main "tool" (contains all windows)
  1296. Xwe have the "header panel." Everything in this panel pertains
  1297. Xto the message headers, only.  The panel in the middle of the
  1298. Xtool is the "mail panel" which is more general and applies to
  1299. Xjust about everything. For a description of each of the items
  1300. Xwithin any panel, select the  "Help"  option  from  the  menu
  1301. Xyou get by selecting the RIGHT mouse button.
  1302. X%%
  1303. X
  1304. X%options%
  1305. XMove the cursor over the option you wish to change.
  1306. XThe LEFT mouse button turns toggles values off and on.
  1307. XThe MIDDLE mouse button displays the meaning of a
  1308. Xvariable. If the option needs typed input, use the LEFT
  1309. Xmouse button.  Sometimes value can be both toggle and
  1310. Xstring values so you may have to click the left button
  1311. Xmore than once to type.  When entering text values, you
  1312. Xmust use RETURN, so the value you typed will be associated
  1313. Xwith the option specified. Unsetting the option will -
  1314. Xassociate the a string value with that option.
  1315. X
  1316. XOnce values are disassociated with options, they can
  1317. Xonly be retrieved by either reentering their values or
  1318. Xby selecting the "restore options" item in the menu.
  1319. XDoing so will read in the last copy of the saved options
  1320. Xfrom your .mailrc file.
  1321. X
  1322. XSelecting the Save option in the menu will save the
  1323. Xcurrent settings in ~/.mailrc.  Selecting the quit
  1324. Xoption in the menu does NOT imply that values are
  1325. Xsaved permanently; changed values will remain through-
  1326. Xout the rest of the mail session.  To save options more
  1327. Xpermanently, select the save menu item.
  1328. X%%
  1329. X
  1330. X%function keys%
  1331. XSelecting the panel item "Opts" with the MENU button will give you
  1332. Xa choice of the type of options you can set. If you choose the one
  1333. Xthat says "function keys", then you can edit the commands that the
  1334. Xfunction keys on the keyboard may execute.  Once in this mode, you
  1335. Xwill find more extensive help.
  1336. X%%
  1337. X
  1338. X%fkeys%
  1339. XUsually the LAST function key in each set (top, left,
  1340. Xand right set of keys) will display the current settings
  1341. Xof all they keys.  The command which does this is 
  1342. X`key_settings X' where X is L, R, or T (left right top)
  1343. Xreferencing the associated function keys.  To set a function
  1344. Xkey to a specific command or set of commands, place the mouse
  1345. Xover the icon image of the key on the screen and click the
  1346. Xleft mouse button.  Type a command from the list of commands
  1347. Xat the bottom of the window and enter RETURN.
  1348. X
  1349. XMany commands take arguments or flags, so be sure to enter
  1350. Xthem here if you want those options. Clicking the middle button
  1351. Xwill display the current value for that key.  If you want to
  1352. Xset a key for multiple commands, separate the commands with
  1353. Xsemicolons:
  1354. X
  1355. XL9:  update ; close
  1356. X
  1357. XThis example would update your mailbox (committing changes)
  1358. Xand close the tool to an icon.
  1359. X%%
  1360. X
  1361. X%message range%
  1362. XYou can specify a large group of messages using a combination of special
  1363. Xsymbols in addition to numbers.  For example, if you wish to save all of
  1364. Xthe messages, then you can use `*' to represent them all. If you were to
  1365. Xtype the  "star" and select the Save  menu option for "save range", then
  1366. Xyou would save ALL the messages you have (including deleted ones).
  1367. X
  1368. XIf you would like to save messages 4 through 9, then you would specify:
  1369. X4-9
  1370. XIf you want to specify the messages between 2 and 32 except for messages
  1371. X6, 8 and message 12-14, you would type:
  1372. X2-32 {6,8,12-14}
  1373. XCommas or spaces can be used to separate numbers.
  1374. X
  1375. XNote that you cannot specify negated messages without first specifying
  1376. Xnormal messages; e.g. {2-5} 1-11   doesn't make sense.
  1377. X%%
  1378. END_OF_FILE
  1379. if test 23232 -ne `wc -c <'tool_help'`; then
  1380.     echo shar: \"'tool_help'\" unpacked with wrong size!
  1381. fi
  1382. # end of 'tool_help'
  1383. fi
  1384. echo shar: End of archive 8 \(of 12\).
  1385. cp /dev/null ark8isdone
  1386. MISSING=""
  1387. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1388.     if test ! -f ark${I}isdone ; then
  1389.     MISSING="${MISSING} ${I}"
  1390.     fi
  1391. done
  1392. if test "${MISSING}" = "" ; then
  1393.     echo You have unpacked all 12 archives.
  1394.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1395. else
  1396.     echo You still need to unpack the following archives:
  1397.     echo "        " ${MISSING}
  1398. fi
  1399. ##  End of shell archive.
  1400. exit 0
  1401.